﻿using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Input;

namespace SharpSoft.WPF.Behaviors
{
    /// <summary>
    /// 管理控件的触摸行为
    /// </summary>
    public class TouchBehavior : Behavior<UIElement>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            foreach (var item in this._tapHandlers)
            { 
                this.AssociatedObject?.AddHandler(TapEvent, item);
            }
            this.AssociatedObject.TouchDown += AssociatedObject_TouchDown;
            this.AssociatedObject.TouchUp += AssociatedObject_TouchUp;
            this.AssociatedObject.TouchMove += AssociatedObject_TouchMove; 
        }


        protected override void OnDetaching()
        {
            base.OnDetaching();
            foreach (var item in this._tapHandlers)
            {
                this.AssociatedObject?.RemoveHandler(TapEvent, item);
            }
            this.AssociatedObject.TouchDown -= AssociatedObject_TouchDown;
            this.AssociatedObject.TouchUp -= AssociatedObject_TouchUp;
        }
        #region Tap

        private List<RoutedEventHandler> _tapHandlers = new List<RoutedEventHandler>();
        /// <summary>
        /// 轻击事件。在行为附加到元素后绑定事件才有效
        /// the tap event.just working when the behavior was attached.
        /// </summary>
        public event RoutedEventHandler Tap
        {
            add
            {
                if (this.AssociatedObject == null)
                {
                    _tapHandlers.Add(value);
                }
                else
                {
                    this.AssociatedObject?.AddHandler(TapEvent, value);
                }

            }
            remove
            {
                if (this.AssociatedObject == null)
                {
                    if (_tapHandlers.Contains(value))
                    {
                        _tapHandlers.Remove(value);
                    }
                }
                else
                {
                    this.AssociatedObject?.RemoveHandler(TapEvent, value);
                }

            }
        }

        public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
        "Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TouchBehavior));

        protected virtual void OnTap()
        {
            RoutedEventArgs args = new RoutedEventArgs();
            args.RoutedEvent = TouchBehavior.TapEvent;
            this.AssociatedObject.RaiseEvent(args);
        }
        #endregion

        #region TouchDelta
         //用户触摸按住并移动，自定义一个事件，参数带有按下的位置、上一帧位置和当前位置
         //20190103，待实现
         //
        #endregion


        /// <summary>
        /// 设置触摸按下与抬起位置偏差的最大值，在这个范围内才认为是有效的触发了Tap事件。默认值为4.
        /// set the validation max distance between touchdown and touchup position for raising Tap event. the default value is 4.
        /// </summary>
        public double MaxChange
        {
            get { return (double)GetValue(MaxChangeProperty); }
            set { SetValue(MaxChangeProperty, value); }
        }
        public static readonly DependencyProperty MaxChangeProperty =
            DependencyProperty.Register("MaxChange", typeof(double), typeof(TouchBehavior), new PropertyMetadata(4d));



        private void AssociatedObject_TouchUp(object sender, System.Windows.Input.TouchEventArgs e)
        {
            if (downPos.HasValue)
            {
                var uppos = e.GetTouchPoint(this.AssociatedObject).Position;
                if ((uppos - downPos.Value).Length <= this.MaxChange)
                {
                    this.OnTap();
                }
                downPos = null;
            }
        }
        private Point? downPos = null;
        private void AssociatedObject_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
        {
            downPos = e.GetTouchPoint(this.AssociatedObject).Position;
        }
        private void AssociatedObject_TouchMove(object sender, System.Windows.Input.TouchEventArgs e)
        {
            throw new NotImplementedException();
        }


    }
}
